package cn.wolfcode.wolf2w.service.impl;

import cn.wolfcode.wolf2w.domain.Destination;
import cn.wolfcode.wolf2w.domain.Region;
import cn.wolfcode.wolf2w.query.DestinationQueryObject;
import cn.wolfcode.wolf2w.redis.service.IRedisService;
import cn.wolfcode.wolf2w.repository.DestinationRepository;
import cn.wolfcode.wolf2w.service.IDestinationService;
import cn.wolfcode.wolf2w.service.IRegionService;
import cn.wolfcode.wolf2w.util.DBHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

@Service
public class DestinationServiceImpl implements IDestinationService {

    @Autowired
    private DestinationRepository destinationRepository;
    @Autowired
    private IRedisService redisService;
    @Autowired
    private IRegionService regionService;

    @Autowired
    private MongoTemplate template;

    @Override
    public void insert(Destination destination) {
        destinationRepository.insert(destination);
        destination.setId(null);
    }

    @Override
    public void delete(String id) {
        destinationRepository.deleteById(id);
    }

    @Override
    public void update(Destination destination) {
        destinationRepository.save(destination);
    }

    @Override
    public Destination selectOne(String id) {
        Destination destination = destinationRepository.findById(id).orElse(null);
        //Destination destination = byId.get();
        return destination;
    }

    @Override
    public List<Destination> selectAll() {
        List<Destination> all = destinationRepository.findAll();
        return all;
    }

    @Override
    public List<Destination> getDestByRegionId(String rid) {
        //1、通过区域id查询区域对象
        Region region = regionService.selectOne(rid);
        //2、从区域对象上获取目的地id的集合
        List<String> refIds = region.getRefIds();
        //3、将目的地id的集合转换成目的地名称的集合
        List<Destination> destinations = destinationRepository.findByIdIn(refIds);
        return destinations;
    }

    @Override
    public Page<Destination> query(DestinationQueryObject q) {
        //1、创建查询对象
        Query query=new Query();
        //2、判断keyword是否为空，若不为空，则进行条件的拼接
        if(StringUtils.hasLength(q.getKeyword())){
            query.addCriteria(Criteria.where("name").regex(q.getKeyword()));//进行拼接高级查询条件时需要使用regex
        }
        //判断父亲id长度是否为空，若为空，拼接成null
        if(!StringUtils.hasLength(q.getParentId())){
            query.addCriteria(Criteria.where("parentId").is(null));
        }else{
            query.addCriteria(Criteria.where("parentId").is(q.getParentId()));
        }
        //3、添加分页语句
        Pageable pageable = PageRequest.of(q.getCurrentPage()-1, q.getPageSize(), Sort.Direction.DESC, "_id");
        Page<Destination> page = DBHelper.query(q,query, Destination.class, template, pageable);
        return page;
    }

    @Override
    public void saveOrUpdate(Destination destination) {
        if(StringUtils.hasLength(destination.getParentId())){
            this.update(destination);
        }else{
            this.insert(destination);
        }
    }

    @Override
    public List<Destination> queryToasts(String parentId) {
        List<Destination> list=new ArrayList<>();
        //使用递归去查询所有当前目的地的上级目的地对象信息
        createToasts(list,parentId);
        //将集合中的元素进行反转
        Collections.reverse(list);
        return list;
    }

    @Override
    public List<Destination> queryDestByRegionForApi(String regionId) {
        List<Destination> list=new ArrayList<>();
        //判断区域id是否为-1，若为-1，则该区域为国内，则查询国内中的所有的省份
        if(regionId.equals("-1")) {
            //此处只能用父级名称为条件进行查询，因为-1是前端给中国的一个id，所以不能以父级的id进行查询
            list = destinationRepository.findByParentName("中国");
        }else {
            list= this.getDestByRegionId(regionId);
        }
        //将该目的地下的子目的地查询出来并封装到list集合中目的地对象中的childern字段当中
        for(Destination dest:list){
            List<Destination> children=destinationRepository.findByParentId(dest.getId());
            //让子目的地不要太多
            //方式1：
            List<Destination> destinations = children.subList(0, 5);
            dest.setChildren(destinations);
        }
        return list;
    }
    //通过层面去查询目的地
    @Override
    public List<Destination> queryByDeep(int deep) {
        List<Destination> list=destinationRepository.queryByDeep(deep);
        return list;
    }

    //通过目的地的名称查询对应的地点
    @Override
    public Destination queryByKeyword(String keyword) {
        Destination destination=destinationRepository.queryByName(keyword);
        return destination;
    }

    private void createToasts(List<Destination> list, String parentId) {
        //判断父亲id长度是否为空（递归的前提条件）
        if(!StringUtils.hasLength(parentId)){
            return;
        }
        Destination destination = this.selectOne(parentId);
        list.add(destination);
        if(StringUtils.hasLength(destination.getParentId())){
            createToasts(list, destination.getParentId());
        }
    }

}
